﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using MayhemCore;
using MayhemWpf.ModuleTypes;
using MayhemWpf.UserControls;
using System.Windows.Threading;
using Total_Mayhem.Common;

namespace Total_Mayhem.Networking
{
    [DataContract]
    [MayhemModule("Computer Leaves Network", "This event monitors for when a computer Leaves your local network.")]
    public class NetworkLeaveEvent : EventBase, IWpfConfigurable
    {

        #region Initialization Code
        protected override void OnLoadDefaults()
        {
            Misc.WriteLog("Entered");
        }

        protected override void OnLoadFromSaved()
        {
            Misc.WriteLog("Entered");
        }

        protected override void OnBeforeLoad()
        {
            Misc.WriteLog("Entered");
        }

        protected override void OnAfterLoad()
        {
            Misc.WriteLog("Entered");
            rnd = new Random();
            //timer = new DispatcherTimer();
            //timer.Tick += Timer_Tick;
            //setInterval(); Will be called by enable method
            timer = new System.Timers.Timer();
            timer.AutoReset = true;
            timer.Elapsed += Timer_Tick;
        }
        #endregion

        private Random rnd;
        //private DispatcherTimer timer;
        private System.Timers.Timer timer;


        private void setInterval()
        {
            if (IntervalinSeconds < 5)
            {
                Misc.WriteLog("Interval was {0}... Setting interval to {1} Seconds.", IntervalinSeconds, 5);
                IntervalinSeconds = 5;
            }
            else
            {
                Misc.WriteLog("Setting interval to {0} Seconds.", IntervalinSeconds);
            }

            //timer.Interval = new TimeSpan(0, 0, IntervalinSeconds);
            timer.Interval = IntervalinSeconds * 1000;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            Misc.WriteLog("Timer fired!");
            SendPingRequest();
        }

        public void SendPingRequest()
        {
            string strResult = "";
            bool bFound = Network.SendPingRequest(ComputerName, out strResult);            
            if (!bFound)
            {
                if (LastCheck)
                {
                    Misc.WriteLog("Ping is not active after last check = true. Execute Trigger!");
                    Dispatcher.CurrentDispatcher.Invoke(new Action(Trigger)); //Run trigger on Dispather thread
                }
                else
                {
                    Misc.WriteLog("Skipping trigger as last check was also false.");
                }
            }
            LastCheck = bFound;
        }

        [DataMember]
        private string ComputerName;

        [DataMember]
        private int IntervalinSeconds;
        
        //[DataMember]
        //private int WaitinMilliSeconds;

        [DataMember]
        private bool LastCheck;

        protected override void OnEnabling(EnablingEventArgs e)
        {
            //base.OnEnabling(e);
            Misc.WriteLog("Entered");
            setInterval();
            timer.Start();
            LastCheck = false; //TODO: what should the default be?

            if (IntervalinSeconds > 5)
            {
                int intNext = rnd.Next(1, 4);
                Misc.WriteLog("Force-checking in {0} seconds...", intNext);
                Dispatcher.CurrentDispatcher.DelayInvoke(new TimeSpan(0, 0, intNext), SendPingRequest); //Force run check after a few seconds
                //Dispatcher.CurrentDispatcher.Invoke(new Action(SendPingRequest), DispatcherPriority.ApplicationIdle,null); 
            }
        }

        protected override void OnDisabled(DisabledEventArgs e)
        {
            //base.OnDisabled(e);
            Misc.WriteLog("Entered");
            timer.Stop();
        }

        public WpfConfiguration ConfigurationControl
        {
            get
            {
                Misc.WriteLog("OpenConfig");
                return new NetworkEventConfig(ComputerName, IntervalinSeconds, "Computer Leaves Network", "leaves");
            }
        }

        public void OnSaved(WpfConfiguration configurationControl)
        {
            NetworkEventConfig nc = configurationControl as NetworkEventConfig;
            if (nc != null)
            {
                Misc.WriteLog("Settings: ComputerName={0} IntervalinSeconds={1}", nc.ComputerName, nc.IntervalinSeconds);
                this.ComputerName = nc.ComputerName;
                this.IntervalinSeconds = nc.IntervalinSeconds;
                //this.WaitinMilliSeconds = nc.WaitinMilliSeconds;
                //setInterval(); Will be called by enable function
            }
        }

        /// <summary>
        /// Used to generate the text that is displayed on the main page of events/triggers to describe this entry
        /// </summary>
        /// <returns></returns>
        public string GetConfigString() { return string.Format("Name: {0}", this.ComputerName); }

    }
}
